/*
*  This file is part of mangusta
*
*  mangusta is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  mangusta is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with mangusta; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US
*
*  Author: <antonino.calderone@ericsson.com>, <acaldmail@gmail.com>
*
*/


/* -------------------------------------------------------------------------- */

#include "nu_variable.h"
#include "nu_exception.h"
#include "nu_lang_defs.h"

#include <set>
#include <cassert>


/* -------------------------------------------------------------------------- */

namespace nu
{


/* -------------------------------------------------------------------------- */

variable_t::type_t variable_t::type_by_typename(const std::string& name)
{
   if (name == PROGLANG_TYPE_INTEGER)
      return type_t::INTEGER;

   if (name == PROGLANG_TYPE_STRING)
      return type_t::STRING;

   if (name == PROGLANG_TYPE_BYTE)
      return type_t::BYTE;

   if (name == PROGLANG_TYPE_DOUBLE)
      return type_t::DOUBLE;

   if (name == PROGLANG_TYPE_FLOAT)
      return type_t::FLOAT;

   if (name == PROGLANG_TYPE_BOOLEAN)
      return type_t::BOOLEAN;

   return type_t::UNDEFINED;
}


/* -------------------------------------------------------------------------- */

bool variable_t::is_valid_name(const std::string& name)
{
   static std::set<std::string> reserved_keywords = PROGLANG_RESERVED_WORDS;

   if (name.empty())
      return false;

   if (reserved_keywords.find(name) != reserved_keywords.cend())
      return false;

   auto letter = [](char c)
   {
      return((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
   };

   char first_char = name.c_str()[0];

   if (!letter(first_char) && first_char != '_')
      return false;

   if (name.size() == 1)
      return first_char != '_';

   auto number = [](char c)
   {
      return(c >= '0' && c <= '9');
   };

   for (size_t i = 1; i < name.size(); ++i)
   {
      char c = name.c_str()[i];

      bool valid = letter(c) || c == '_' || number(c);

      if (!valid)
         return false;
   }

   return true;
}


/* -------------------------------------------------------------------------- */

}


/* -------------------------------------------------------------------------- */
